home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
POPCLI.C
< prev
next >
Wrap
Text File
|
1993-10-14
|
6KB
|
266 lines
/*
* POP2 Client routines. Originally authored by Mike Stockett (WA7DYX).
*
* Modified 12 May 1991 by Mark Edwards (WA6SMN) to use new timer
* facilities in NOS0423. Fixed type mismatches spotted by C++.
* Modified 27 May 1990 by Allen Gwinn (N5CKP) for compatibility
* with later releases (NOS0522).
* Added into NOS by PA0GRI (and linted into "standard" C)
*
* Some code culled from previous releases of SMTP.
*
* Client routines for Simple Mail Transfer Protocol ala RFC821
* A.D. Barksdale Garbee II, aka Bdale, N3EUA
* Copyright 1986 Bdale Garbee, All Rights Reserved.
* Permission granted for non-commercial copying and use, provided
* this notice is retained.
* Modified 14 June 1987 by P. Karn for symbolic target addresses,
* also rebuilt locking mechanism
* Copyright 1987 1988 David Trulli, All Rights Reserved.
* Permission granted for non-commercial copying and use, provided
* this notice is retained.
*/
#include <stdio.h>
#include <conio.h>
#include "global.h"
#include "config.h"
#ifdef POP
#include "cmdparse.h"
#include "socket.h"
#include "netuser.h"
#include "files.h"
#include "smtp.h"
#include "pop.h"
#include "clients.h"
static int16 Popquiet = 0;
static void
poppoll(int unused,void *cb1,void *p)
{
struct sockaddr_in fsocket;
char *cp, fname[MAXPATH];
int32 msgid = 0;
struct popcli *ccb;
struct Server *np = (struct Server *)cb1;
fsocket.sin_family = AF_INET;
fsocket.sin_addr.s_addr = np->address;
fsocket.sin_port = IPPORT_POP;
np->busy = TRUE;
ccb = mxallocw(sizeof(struct popcli));
ccb->buf = mxallocw(BUF_LEN);
cli_login(IPPORT_POP,(void *)np);
if(np->arg1 == NULLCHAR
|| np->arg2 == NULLCHAR
|| np->arg3 == NULLCHAR) {
tputs("Missing entries in structure\n");
goto quit;
}
if((ccb->socket = socket(AF_INET,SOCK_STREAM,0)) == -1) {
goto quit;
}
sockmode(ccb->socket,SOCK_ASCII);
if(connect(ccb->socket,(char *)&fsocket,SOCKSIZE) != -1) {
log(ccb->socket,9983,"POP connect");
ccb->state = CALL;
for(; ; ) {
loop:
if(ccb->state == EXIT) {
usputs(ccb->socket,"QUIT\n");
break;
}
if(recvline(ccb->socket,ccb->buf,BUF_LEN) == -1) {
break;
}
rip(ccb->buf);
switch(ccb->state) {
case CALL:
if(strncmp(ccb->buf,"+ POP2 ",7) == 0) {
usprintf(ccb->socket,"HELO %s %s\n",np->arg2,np->arg3);
ccb->state = NMBR;
} else {
ccb->state = EXIT;
}
goto loop;
case NMBR:
switch(*ccb->buf) {
case '#':
usputs(ccb->socket,"READ\n");
ccb->state = SIZE;
break;
default:
/* case '+': */
/* If there is no mail (the only time we get a "+"
* response back at this stage of the game),
* then just close out the connection, because
* there is nothing more to do!! */
ccb->state = EXIT;
}
goto loop;
case SIZE:
if(*ccb->buf == '=') {
if((ccb->msg_len = atol(&(ccb->buf[1]))) > 0) {
msgid = get_msgid();
sprintf(fname,"%s/%ld.txt",Mailqdir,msgid);
if((ccb->fd = Fopen(fname,WRITE_TEXT,0,1)) != NULLFILE) {
usputs(ccb->socket,"RETR\n");
ccb->state = XFER;
goto loop;
}
}
}
ccb->state = EXIT;
goto loop;
case XFER:
fprintf(ccb->fd,"%s\n",ccb->buf);
/* Add CRLF */
if((ccb->msg_len -= (long)(strlen(ccb->buf)+2)) > 0) {
goto loop;
}
/* All done, so do local cleanup */
Fclose(ccb->fd);
sprintf(fname,"%s/%ld.wrk",Mailqdir,msgid);
if((ccb->fd = Fopen(fname,WRITE_TEXT,0,1)) != NULLFILE) {
fprintf(ccb->fd,"%s\n%s\n\%s\n",Hostname,np->name,np->arg1);
Fclose(ccb->fd);
}
usputs(ccb->socket,"ACKD\n");
switch(Popquiet) {
case 0:
putch(7);
case 1:
/* timestamp by dc3sn */
tprintf("POP: new mail for %s from %s at %s\n",
np->arg1,np->name,timestr(currtime));
break;
case 3:
log(-1,IPPORT_POP,"POP new mail from %s",np->name);
break;
}
ccb->state = SIZE;
default:
goto loop;
}
}
}
if(ccb->fd != NULLFILE) {
Fclose(ccb->fd);
}
if((cp = sockerr(ccb->socket)) == NULLCHAR) {
cp = "EOF";
}
log(ccb->socket,9983,"POP closed %s",cp);
recvline(ccb->socket,ccb->buf,BUF_LEN);
close_s(ccb->socket);
quit:
xfree(ccb->buf);
xfree(ccb);
np->busy = FALSE;
return;
}
/* --------------------------- Popcli subcmds ----------------------------- */
static int
dopopadds(int argc,char **argv,void *p)
{
struct Server *np;
if((np = addserver(IPPORT_POP,argv[1])) == NULLSERVER) {
return -1;
}
if(argc == 2) {
if(!(cli_login(IPPORT_POP,(void *)np))) {
tputs("No userdata in file\n");
}
return 0;
}
if(argc != 5) {
tputs("Syntax error\n");
return -1;
}
np->arg1 = strxdup(argv[2]);
np->arg2 = strxdup(argv[3]);
np->arg3 = strxdup(argv[4]);
return 0;
}
/* drops servers from list */
static int
dopopdrops(int argc,char **argv,void *p)
{
dropserver(IPPORT_POP,argv[1]);
return 0;
}
static int
popkick(int argc,char **argv,void *p)
{
int32 addr = 0;
struct Server *np;
if(argc > 1 && (addr = resolve(argv[1])) == 0){
tprintf(Badhost,argv[1]);
return 1;
}
for(np = Server; np != NULLSERVER; np = np->next) {
if(np->protocol != IPPORT_POP
|| np->busy
|| (addr && (np->address != addr))) {
continue;
} else {
newproc("POP Client",1024,poppoll,0,(void *)np,0,0);
}
}
return 0;
}
static int
dopoplists(int argc,char **argv,void *p)
{
static char *a = "Mailbox User";
listserver(IPPORT_POP,argv[1],a);
return 0;
}
static int
doquiet(int argc,char **argv,void *p)
{
return setintrc(&Popquiet,"POP quiet",argc,argv,0,3);
}
int
dopop(int argc,char **argv,void *p)
{
struct cmds Popcmds[] = {
{"add", dopopadds, 0, 2, "pop add <server> [<mailbox> <user> <pass>]"},
{"drop", dopopdrops, 0, 2, "pop drop <server>"},
{"list", dopoplists, 0, 0, NULLCHAR},
{"kick", popkick, 0, 0, NULLCHAR},
{"quiet", doquiet, 0, 0, NULLCHAR},
NULLCHAR,
};
return subcmd(Popcmds,argc,argv,p);
}
#endif /* POP */